/**
 * @fileoverview Giant Interective Group, Inc. Javascript Library v2.0.3.
 * 城市级联列表控件。
 * <pre>
 * Copyright (C) 2004-2009 Giant Interective Group, Inc. All rights reserved.
 * 版权所有 2004-2009 上海巨人网络科技有限公司
 * </pre>
 * 
 * @version 2.0.3, 2009-05-22 11:40:52
 * @author  Fuchun
 * Depends on jQuery 1.3.x
 * Depends on giant.core 2.0.x
 * Depends on ui.component 2.0.x
 */

(function($) {

var isCrossdomain = false;
var provincesCache = [], citiesCache = {}, countiesCache = {};
var PROVINCE_URL = '/commons/' + GiantAjax.LOAD + 'ProvinceList.do',
    CITY_URL = '/commons/' + GiantAjax.LOAD + 'CityList.do',
    COUNTY_URL = '/commons/' + GiantAjax.LOAD + 'CountyList.do';
var CITY_AND_COUNTY_URL = '/commons/' + GiantAjax.LOAD + 'CityAndCountyList.do';
var PROVINCE = 1, CITY = 2, COUNTY = 3;

/**
 * 新建一个城市级联列表控件。
 * @class giant.ui.City 城市级联列表控件。
 * @example
 * <pre><span class="annotate">// Html代码如下：</span>
 * &lt;select id="cmb_home_provinces"&gt;&lt;/select&gt;
 * &lt;select id="cmb_home_cities"&gt;&lt;/select&gt;
 * &lt;select id="cmb_home_counties"&gt;&lt;/select&gt;
 * 
 * <span class="annotate">// 简捷的调用方法：</span>
 * $(document).ready(function() {
 *     $.city({
 *         province: 'cmb_home_provinces',
 *         city: 'cmb_home_cities',
 *         county: 'cmb_home_counties',
 *         crossdomain: true <span class="annotate">// 进行跨域调用</span>
 *     }, {
 *         <span class="annotate">// 初始化时选中的各项的值</span>
 *         province: '110000', city: '110100', county: '110110'
 *     });
 * });
 * </pre>
 * 
 * @constructor
 * @param {Object} options 控件的配置参数。<br>
 *          options.province    --&gt;  省份下拉列表控件Id。<br>
 *          options.city        --&gt;  市区下拉列表控件Id。<br>
 *          options.county      --&gt;  县区下拉列表控件Id。<strong>（可选）</strong><br>
 *          options.crossdomain --&gt;  是否进行跨域调用。<strong>默认为 false</strong><br>
 * @param {Object} defaults 控件的初始值配置。
 *          options.province    --&gt;  省份下拉列表的初始化选中的值(省份编码)。<br>
 *          options.city        --&gt;  市区下拉列表的初始化选中的值(市编码)。<br>
 *          options.county      --&gt;  县区下拉列表的初始化选中的值(县编码)。
 * @returns {giant.ui.City} 返回新的城市级联列表控件实例。
 */
giant.ui.City = function(options, defaults) {
    var s = this.s = giant.extend({
	    province: 'cmb_provinces',
	    city: 'cmb_cities',
	    county: 'cmb_counties',
	    async: false,
	    crossdomain: isCrossdomain
	}, options, true);
    var d = this.d = giant.extend({
    	province: '', city: '', county: ''
    }, defaults, true);
    var jProvinceId = s.province.startsWith('#') ? s.province : '#' + s.province,
        jCityId = s.city.startsWith('#') ? s.city : '#' + s.city,
        jCountyId = s.county.startsWith('#') ? s.county: '#' + s.county;
    isCrossdomain = s.crossdomain || false;
    this.provLocationId = -1;
    this.cityLocationId = -1;
    this.countyLocationId = -1;
    this.jProvince = $.combobox({id:jProvinceId});
    this.jCity = $.combobox({id:jCityId});
    if($(jCountyId).length !== 0)
        this.jCounty = $.combobox({id:jCountyId});
    else
        this.jCounty = null;
    this.initComponent(this.s, this.d);
};

/**@#+
 * @memberOf giant.ui.City
 * @method
 */
giant.ui.City.prototype = {
    
    // 初始化城市级联列表控件
    initComponent: function(options, defaults) {
        var $self = this;
        var jcmbCity = this.jCity.getJComboBox(),
            jcmbCounty = this.jCounty == null ? null : this.jCounty.getJComboBox();
        var selectProvince = function(proId, callback) {
            requestCityAndCountyList(proId, function() {
                var first = jcmbCity.find('option:first');
                if(jcmbCounty != null) {
                    var countyFirst = jcmbCounty.find('option:first');
                    jcmbCounty.empty();
                    countyFirst.appendTo(jcmbCounty);
                }
                jcmbCity.empty();
                first.appendTo(jcmbCity);
                var cityList = citiesCache[proId] || [];
                $self.jCity.addItem(cityList);
                
                if(proId == -1) {
                    $self.countyLocationId = -1;
                    $self.cityLocationId = -1;
                    $self.provLocationId = -1;
                } else {
                    for(var i = 0, len = provincesCache.length; i < len; i++) {
                        if(proId == provincesCache[i].value) {
                            $self.provLocationId = provincesCache[i].id;
                            break;
                        }
                    }
                }
                if(giant.isFunction(callback))
                    callback($self.jProvince.getComboBox());
            });
        };
        var selectCity = function(provId, cityId, callback) {
            requestCounties(cityId, function() {
                if(jcmbCounty != null) {
                	var first = jcmbCounty.find('option:first');
	                jcmbCounty.empty();
	                first.appendTo(jcmbCounty);
	                var countyList = countiesCache[cityId];
	                $self.jCounty.addItem(countyList);
                }
                var cityList = citiesCache[provId] || [];
                if(cityList && cityList.length > 0) {
                    for(var i = 0, len = cityList.length; i < len; i++) {
                        if(cityId == cityList[i].value) {
                            $self.cityLocationId = cityList[i].id;
                            break;
                        }
                    }
                }
                if(cityId == -1) {
                    $self.countyLocationId = -1;
                    $self.cityLocationId = -1;
                    if(provId == -1) {
                        $self.provLocationId = -1;
                    } else {
                        for(var i = 0, len = provincesCache.length; i < len; i++) {
                            if(provId == provincesCache[i].value) {
                                $self.provLocationId = provincesCache[i].id;
                                break;
                            }
                        }
                    }
                }
                if(giant.isFunction(callback))
                    callback($self.jCity.getComboBox());
            });
        };
        var selectCounty = function(provId, cityId, countyId) {
            var countyList = countiesCache[cityId] || [];
            for(var i = 0, len = countyList.length; i < len; i++) {
                if(countyId == countyList[i].value) {
                    $self.countyLocationId = countyList[i].id;
                    break;
                }
            }
            if(countyId == -1) {
                $self.countyLocationId = -1;
                if(cityId == -1)
                    $self.cityLocationId = -1;
                if(provId == -1)
                    $self.provLocationId = -1;
            }
        };
        this.jProvince.addEvent('change', function() {
            selectProvince(this.value);
        });
        this.jCity.addEvent('change', function() {
            selectCity($self.jProvince.value(), this.value);
        });
        if(this.jCounty != null) {
            this.jCounty.addEvent('change', function() {
                var provId = $self.jProvince.value(),
                cityId = $self.jCity.value(),
                countyId = this.value;
                selectCounty(provId, cityId, countyId);
            });
        }
        if(this.jProvince.length() <= 1) {
            if(provincesCache.length === 0) {
                requestProvinces(this.s, function() {
                    $self.jProvince.addItem(provincesCache, function() {
                    	if($self.d.province != '') {
			                $self.jProvince.select({value: $self.d.province});
			            }
                    });
                    selectProvince($self.d.province, function(cmbProv) {
                        if($self.d.city != '')
                            $self.jCity.select({value: $self.d.city});
                        selectCity($self.d.province, $self.d.city, function(cmbCity) {
                            if($self.d.county != '' && $self.jCounty != null) {
                            	$self.jCounty.select({value: $self.d.county});
                                selectCounty($self.d.province, $self.d.city, $self.d.county);
                            }
                        });
                    });
                });
            } else {
                this.jProvince.addItem(provincesCache);
            }
        }
    },
    
    /**
     * 获取当前选项的城市Id。
     * 
     * @returns {String} 当前选项的城市Id。
     */
    getLocationId: function() {
    	if(this.countyLocationId !== -1) {
            return this.countyLocationId;
        }
        if(this.cityLocationId !== -1) {
        	return this.cityLocationId;
        }
        if(this.provLocationId !== -1) {
        	return this.provLocationId;
        }
        return -1;
    }
};
/**@#-*/

$.city = function(options, defaults) {
	return new giant.ui.City(options, defaults);
};

function requestProvinces(options, callback) {
    if(provincesCache.length !== 0) {
    	callback.call(provincesCache);
        return;
    }
    isCrossdomain = options.crossdomain || false;
    GiantAjax.responseJson({
        crossdomain: isCrossdomain,
        url: PROVINCE_URL,
        async: options.async || true,
        success: function(jsonData) {
            for(var i = 0, len = jsonData.length; i < len; i++) {
                provincesCache[i] = {
                    id: jsonData[i].id,
                    text: jsonData[i].proName, 
                    value: jsonData[i].proId,
                    direct: jsonData[i].direct
                };
            }
            callback.call(provincesCache);
        }
    });
}

function requestCityAndCountyList(provId, callback) {
    if(citiesCache[provId] && citiesCache[provId].length !== 0) {
        callback.call(citiesCache[provId]);
        return;
    }
    citiesCache[provId] = [];
    GiantAjax.responseJson({
        crossdomain: isCrossdomain,
        url: CITY_AND_COUNTY_URL,
        params: { provId:provId },
        success: function(jsonData) {
            for(var i = 0, len = jsonData.length; i < len; i++) {
            	if(jsonData[i].type === CITY) {
            		citiesCache[provId].push({
	                    id: jsonData[i].id,
	                    text: jsonData[i].cityName,
	                    value: jsonData[i].cityId
	                });
            	} else if(jsonData[i].type === COUNTY) {
            		if(!countiesCache[jsonData[i].cityId] ||
            		        countiesCache[jsonData[i].cityId].length === 0) {
            		    countiesCache[jsonData[i].cityId] = [];
            		}
            		countiesCache[jsonData[i].cityId].push({
            			id: jsonData[i].id,
	                    text: jsonData[i].countyName,
	                    value: jsonData[i].countyId
            		});
            	}
            }
            callback.call(citiesCache[provId]);
        }
    });
}

function requestCounties(cityId, callback) {
    if(countiesCache[cityId] && countiesCache[cityId].length !== 0) {
    	callback.call(countiesCache[cityId]);
        return;
    } else if(cityId == -1) {
    	callback.call(countiesCache[cityId]);
        return;
    }
    countiesCache[cityId] = [];
    GiantAjax.responseJson({
        crossdomain: isCrossdomain,
        url: COUNTY_URL,
        params: { cId: cityId },
        success: function(jsonData) {
            for(var i = 0, len = jsonData.length; i < len; i++) {
                countiesCache[cityId].push({
                    id: jsonData[i].id,
                    text: jsonData[i].countyName,
                    value: jsonData[i].countyId
                });
            }
            callback.call(countiesCache[cityId]);
        }
    });
}
})(jQuery);